namespace Neovolve.Extensibility.ReSharper
{
    using System;
    using JetBrains.Application.Progress;
    using JetBrains.ProjectModel;
    using JetBrains.ReSharper.Feature.Services.Bulbs;
    using JetBrains.ReSharper.Intentions;
    using JetBrains.TextControl;
    using JetBrains.Util;

    /// <summary>
    /// The <see cref="ConvertTypeQuickFix"/>
    ///   class is an abstract class that helps with converting between Clr and alias types.
    /// </summary>
    [CLSCompliant(false)]
    public abstract class ConvertTypeQuickFix : BulbItemImpl, IQuickFix
    {
        /// <summary>
        /// Stores the highlighting related to the quick fix.
        /// </summary>
        private readonly ConvertTypeHighlighting _highlighter;

        /// <summary>
        /// Initializes a new instance of the <see cref="ConvertTypeQuickFix"/> class.
        /// </summary>
        /// <param name="highlighter">
        /// The highlighter.
        /// </param>
        protected ConvertTypeQuickFix(ConvertTypeHighlighting highlighter)
        {
            _highlighter = highlighter;
        }

        /// <summary>
        /// Check if this action is available at the constructed context.
        ///   Actions could store pre-calculated info in <paramref name="cache"/> to share it between different actions.
        /// </summary>
        /// <param name="cache">
        /// The cache value.
        /// </param>
        /// <returns>
        /// <c>true</c> if the action is available; otherwise <c>false</c>.
        /// </returns>
        public Boolean IsAvailable(IUserDataHolder cache)
        {
            return _highlighter.BulbItem.Descriptor.IsValid;
        }

        /// <summary>
        /// Executes QuickFix or ContextAction. Returns post-execute method.
        /// </summary>
        /// <param name="solution">
        /// The solution for the action.
        /// </param>
        /// <param name="progress">
        /// The progress for the action.
        /// </param>
        /// <returns>
        /// Method to execute after PSI transaction finish. Use to open TextControls, navigate caret, etc.
        /// </returns>
        protected override Action<ITextControl> ExecuteTransaction(ISolution solution, IProgressIndicator progress)
        {
            _highlighter.BulbItem.Execute(solution, null);

            return null;
        }

        /// <summary>
        /// Popup menu item text.
        /// </summary>
        /// <value>
        /// The text.
        /// </value>
        public override String Text
        {
            get
            {
                return _highlighter.BulbItem.Text;
            }
        }

        /// <summary>
        /// Gets the type of the node search.
        /// </summary>
        /// <value>
        /// The type of the node search.
        /// </value>
        protected abstract TypeAliasFormat NodeSearchType
        {
            get;
        }
    }
}